// -----------------------------------------------------------------------
//  <copyright file="GetRoleNodeQuery.cs" company="LiuliuSoft">
//      Copyright (c) 2022-2024 DaprPlus. All rights reserved.
//  </copyright>
//  <site>https://dapr.plus</site>
//  <last-editor>郭明锋</last-editor>
//  <last-date>2024/12/10 11:01:41</last-date>
// -----------------------------------------------------------------------

using Liuliu.Fsb.Services.Identity.Domain.Entities;
using Microsoft.EntityFrameworkCore;
using DaprPlus.Domain.Entity;

namespace Liuliu.Fsb.Services.Identity.Application.Identity.Roles.Queries;

/// <summary>
/// 获取角色节点查询
/// </summary>
[AuthConfig(typeof(Role), ResourceAccessType.RoleLimit, "GetNode")]
public class GetRoleNodeQuery : SingleQuery<List<RoleNodeDto>>
{
    /// <summary>
    /// 用户ID，可选参数
    /// </summary>
    public long? UserId { get; set; }
}

/// <summary>
/// 获取角色节点查询处理程序
/// </summary>
public class GetRoleNodeQueryHandler(IQueryRepository<Role> queryRepository, IQueryRepository<UserRole> userRoleRepository)
    : IRequestHandler<GetRoleNodeQuery, List<RoleNodeDto>>
{
    public async Task<List<RoleNodeDto>> Handle(GetRoleNodeQuery request, CancellationToken cancellationToken)
    {
        var spec = new RoleUnlockedSpec<Role>();
        var roles = await queryRepository.GetAllAsync<RoleNodeDto>(spec, cancellationToken);

        // 如果提供了用户ID，则标记用户已有的角色
        if (request.UserId.HasValue)
        {
            var userRoleSpec = new UserRoleForUserSpec<UserRole>(request.UserId.Value);
            var userRoles = await userRoleRepository.GetAllAsync(userRoleSpec, cancellationToken);
            var userRoleIds = userRoles.Select(ur => ur.RoleId).ToHashSet();

            foreach (var role in roles)
            {
                role.IsSelected = userRoleIds.Contains(role.Id);
            }
        }

        return roles;
    }
}

/// <summary>
/// 角色节点数据传输对象
/// </summary>
[MapFrom(typeof(Role))]
public class RoleNodeDto
{
    /// <summary>
    /// 角色ID
    /// </summary>
    public long Id { get; set; }

    /// <summary>
    /// 角色名称
    /// </summary>
    public required string Name { get; set; }

    /// <summary>
    /// 是否已选中（用户已拥有此角色）
    /// </summary>
    public bool IsSelected { get; set; }
}

